package cn.zc.utils;

import cn.zc.constant.KeyVaultConstant;
import cn.zc.entity.Cource;
import cn.zc.entity.CourceSQL;
import cn.zc.entity.User;
import cn.zc.mapper.AdminMapper;
import cn.zc.mapper.CourceMapper;
import cn.zc.mapper.StudentMapper;
import cn.zc.service.AdminService;
import okhttp3.*;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;

import java.util.ArrayList;
import java.util.Base64;
import java.net.URLEncoder;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.zc.constant.KeyVaultConstant.API_KEY;
import static cn.zc.constant.KeyVaultConstant.SECRET_KEY;


/**
 * 需要添加依赖
 * <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
 * <dependency>
 *     <groupId>com.squareup.okhttp3</groupId>
 *     <artifactId>okhttp</artifactId>
 *     <version>4.12.0</version>
 * </dependency>
 */

public class CourceUtils {


    static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

    /**
     * 获取OCR识别文字结果
     * @param imageBath
     * @return
     * @throws IOException
     */
    public static String getOCRResult(byte[] imageBath) throws IOException{
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        // image 可以通过 getFileContentAsBase64("C:\fakepath\z.png") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
        RequestBody body = RequestBody.create(mediaType, "image=" + getFileContentAsBase64(imageBath, true));
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=" + getAccessToken())
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        return response.body().string();
    }

    /**
     * 获取文件base64编码
     *
     * @param b      图片的字节数组
     * @param urlEncode 如果Content-Type是application/x-www-form-urlencoded时,传true
     * @return base64编码信息，不带文件头
     * @throws IOException IO异常
     */
    static String getFileContentAsBase64(byte[] b, boolean urlEncode) throws IOException {
//        byte[] b = Files.readAllBytes(Paths.get(path));
        String base64 = Base64.getEncoder().encodeToString(b);
        if (urlEncode) {
            base64 = URLEncoder.encode(base64, "utf-8");
        }
        return base64;
    }


    /**
     * 从用户的AK，SK生成鉴权签名（Access Token）
     *
     * @return 鉴权签名（Access Token）
     * @throws IOException IO异常
     */
    static String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY
                + "&client_secret=" + SECRET_KEY);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        return new JSONObject(response.body().string()).getString("access_token");
    }
    /**
     * 返回给前端的课程信息
     */
    public static List<CourceSQL> getCourceVo(List<Cource> cources, String studentId) {

        List<CourceSQL> courceList = new ArrayList<>();
        for (Cource cource : cources){
            CourceSQL courceSQL = new CourceSQL();
            //设置学生id
            courceSQL.setStudentId(studentId);
            //设置开始周
            courceSQL.setStart_week(cource.getWeeks().get(0));
            //设置结束周
            courceSQL.setEnd_week(cource.getWeeks().get(cource.getWeeks().size()-1));
            //设置周类型
            courceSQL.setWeekType(cource.getWeekType());
            //设置第几节课
            int period = cource.getStartSection();
            switch (period){
                case 1:
                    courceSQL.setPeriod(1);
                    break;
                case 3:
                    courceSQL.setPeriod(2);
                    break;
                case 5:
                    courceSQL.setPeriod(3);
                    break;
                case 7:
                    courceSQL.setPeriod(4);
                    break;
                case 9:
                    courceSQL.setPeriod(5);
                    break;
                case 11:
                    courceSQL.setPeriod(6);
                    break;
            }
            courceSQL.setDayOfWeek(cource.getDayOfWeek());
            courceList.add(courceSQL);
        }
        return courceList;
    }
    public static List<CourceSQL> setIsOverlap(List<CourceSQL> courceList,int week) {
        courceList.sort(Comparator.comparingInt(CourceSQL::getDayOfWeek)
                .thenComparingInt(CourceSQL::getPeriod));
        List<Integer> arr=new ArrayList<>();
        for (CourceSQL cource : courceList) {
            if(cource.getWeekType() == 0){
                int startWeek = cource.getStart_week();
                int endWeek = cource.getEnd_week();
                arr=new ArrayList<>();
                if (startWeek==endWeek&&startWeek==0){
                    for (int i = 1; i <= 16; i++) {
                        arr.add(i);
                    }
                }else if(startWeek==endWeek){
                    for (int i = 1; i <=16 ; i++) {
                        if(i!=startWeek){
                            arr.add(i);
                        }
                    }
                }else {
                    for (int i = 1; i <= 16; i++) {
                        if(i>endWeek||i<startWeek){
                            arr.add(i);
                        }
                    }
                }


            } else if (cource.getWeekType() == 2) {
                arr=new ArrayList<>();
                int startWeek = cource.getStart_week();
                int endWeek = cource.getEnd_week();
                for (int i = 1; i <= 16; i++) {
                    if ((i < startWeek || i > endWeek)) {
                        arr.add(i);
                    }else if (i%2!=0){
                        arr.add(i);
                    }
                }

            } else if (cource.getWeekType() == 1) {
                 arr=new ArrayList<>();
                 int startWeek = cource.getStart_week();
                 int endWeek = cource.getEnd_week();
                for (int i = 1; i <= 16; i++) {
                    if ((i < startWeek || i > endWeek)) {
                        arr.add(i);
                    }else if (i%2==0){
                        arr.add(i);
                    }
                }
            }
            //arr为需要签到的周数，判断当前周是否在里面，在则设置为-1说明本周的这节课不需要签到
            if(!arr.contains(week)){
                cource.setIsover(-1);
            }else {
                cource.setIsover(0);
            }
        }
        //将所有需要连续签到的课程设置为-1
        List<CourceSQL> courceSQLS = checkIsOverlap(courceList, 3);
        return courceSQLS;
    }
    public static List<CourceSQL> checkIsOverlap(List<CourceSQL> courceList, int stop) {
        int next=0;
        ArrayList<Integer> integers = new ArrayList<>();
        while (next<courceList.size()-1) {
                CourceSQL courceSQL1 = courceList.get(next);
                CourceSQL courceSQL2 = courceList.get(next+1);
                if (courceSQL1.getDayOfWeek() == courceSQL2.getDayOfWeek()
                        && courceSQL1.getPeriod()+1 == courceSQL2.getPeriod()
                &&courceSQL2.getPeriod()!=stop
                &&courceSQL1.getIsover()==0) {
                        integers.add(next+1);
                }
                next++;
            }
        for (int i = 0; i < integers.size(); i++) {
            courceList.get(integers.get(i)).setIsover(-1);
        }
            return courceList;
    }
    //重置课程，清空登录日志，迟到数据

}